﻿/*
 *Copyright(C) 2024 by CometGamming All rights reserved.
 *Unity版本：2022.3.43f1c1 
 *作者:程一峰  
 *创建日期: 2024-10-07 
 *模块说明：第1章：数学和物理学初探
 *版本: 0.1.0
*/

using Sirenix.OdinInspector;
using System;
using Unity.Mathematics;
using UnityEngine;

namespace GameAIStudy
{
    /// <summary>
    /// 第1章：数学和物理学初探的示例代码；
    /// </summary>
    public class MathAndPhysics : MonoBehaviour
    {

        /// <summary>
        /// 一些数学部分
        /// </summary>
        public void MathMethods()
        {
            //指数：
            Mathf.Pow(4, 2); // 16
            math.pow(5, 2);//  25
            Math.Pow(6, 2);//36

            //幂 --  Unity.Mathematics 没有自定义底数的方法，只有调用 C# 原生方法
            Mathf.Log(16, 2);//4
            Mathf.Sqrt(16);//4 平方的另一种写法

            math.log(25);//自然对数
            math.log2(25);//平方
            math.log10(25);//以10为底
            Math.Log(25, 2);//5

            //三角函数：注意，这里的角度都是弧度制
            Mathf.Sin(Mathf.PI * 2);//正弦
            Mathf.Asin(1);//反正弦
            Mathf.Cos(3);//余弦
            Mathf.Acos(2);//反余弦
            Mathf.Tan(Mathf.PI * 2);//正切
            Mathf.Atan(2);//反正切

            math.sin(Mathf.PI * 2);//正弦
            math.asin(2);//反正弦
            math.cos(Mathf.PI * 2);//余弦
            math.acos(2);//反余弦
            math.tan(Mathf.PI * 2);//正切
            math.atan(2);//反正切
            math.sincos(math.PI * 2, out float _, out float _);//同时计算正弦值和余弦值；
        }

        public static void VectorMethod()
        {
            var v1 = new Vector2(1, 1);
            var v2 = new Vector3(1, 1, 1);

            var v3 = new float2(1, 1);
            var v4 = new float3(1, 1, 1);

            //点乘
            var dot1 = Vector3.Dot(v2, v2);
            var dto2 = math.dot(v4, v4);

            //叉乘
            var cross1 = Vector3.Cross(v2, v2);
            var corss2 = math.cross(v4, v4);

        }

        [LabelText("向量A")]
        public Vector3 VecA = Vector3.one;

        [LabelText("向量B")]
        public Vector3 VecB = Vector3.one;

        [Button("向量乘法")]
        public void TestVec()
        {
            Debug.Log($"向量【{VecA}】和向量【{VecB}】点乘结果：{Vector3.Dot(VecA, VecB)}");
            Debug.Log($"向量【{VecA}】和向量【{VecB}】叉乘结果：{Vector3.Cross(VecA, VecB)}");
        }

        [Button("向量模长和距离")]
        public void TestVec2()
        {
            Debug.Log($"向量【{VecA}】模长：{VecA.magnitude}");//向量模长
            Debug.Log($"向量【{VecA}】归一化：{VecA.normalized}");//归一化、标准化
            Debug.Log($"向量【{VecA}】和向量【{VecB}】距离：{Vector3.Distance(VecA, VecB)}");//两点之间的距离
        }

        [Button("测试矩阵")]
        public void TestMatrix()
        {
            //本地坐标转换为世界坐标的矩阵
            Matrix4x4 localToWorld = transform.localToWorldMatrix;

            //将本地坐标转换为世界坐标
            Vector3 localPosition = VecA;
            Vector3 worldPosition = localToWorld.MultiplyPoint3x4(localPosition);
            Debug.Log($"本地坐标 【{localPosition}】 转换为世界坐标：{worldPosition}");

            //世界坐标转换为本地坐标的矩阵
            Matrix4x4 worldToLocal = transform.worldToLocalMatrix;
            localPosition = worldToLocal.MultiplyPoint3x4(worldPosition);
            Debug.Log($"世界坐标 【{worldPosition}】 转换为本地界坐标：{localPosition}");

            //Unity.Mathematics 里的写法
            float4x4 matrix = math.float4x4(localToWorld.GetColumn(0), localToWorld.GetColumn(1), localToWorld.GetColumn(2), localToWorld.GetColumn(3));
            worldPosition = math.mul(matrix, new float4(localPosition, 1)).xyz;
            Debug.Log($"本地坐标 【{localPosition}】 转换为世界坐标：{worldPosition}");

            //手动构建矩阵；
            localToWorld = Matrix4x4.TRS(transform.position, transform.rotation, transform.localScale);
            worldToLocal = localToWorld.inverse;//矩阵翻转
        }

        public void PhysicsMethods()
        {
            float deltaTime = Time.deltaTime;//帧时间（秒）
            float realTime = Time.realtimeSinceStartup;//从游戏开始时的真实时间（秒）
        }


    }
}